﻿using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows;
using System.Windows.Input;
using Microsoft.Win32;
using MVVMFoundation;

namespace DictationTool.ViewModel
{
    class MainWindowViewModel : ObservableObject
    {
        public MainWindowViewModel()
        {
            MediaPlayerViewModel = new MediaPlayerViewModel();
            MediaPlayerViewModel.Loaded += HandleMediaLoaded;
        }

        #region Properties

        public MediaPlayerViewModel MediaPlayerViewModel { get; private set; }

        public DictationViewModel DictationViewModel
        {
            get { return dictationViewModel; }
            set
            {
                dictationViewModel = value;
                base.RaisePropertyChanged("DictationViewModel");
            }
        }

        /// <summary>
        /// Open a media file.
        /// </summary>
        public ICommand OpenMediaCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    MediaPlayerViewModel.LoadCommand.Execute(null);
                });
            }
        }

        /// <summary>
        /// Open a dct file to continue dictation
        /// </summary>
        public ICommand OpenCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    if (CheckSave() != MessageBoxResult.Cancel)
                    {
                        OpenFileDialog dlg = new OpenFileDialog();
                        dlg.Filter = "dct | *.dct";
                        if (dlg.ShowDialog() == true)
                        {
                            using (var stream = File.Open(dlg.FileName, FileMode.Open))
                            {
                                DeserializeResult(stream);
                            }
                        }
                    }
                });
            }
        }

        /// <summary>
        /// Save dictation to a dct file
        /// </summary>
        public ICommand SaveFileCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    SaveFileDialog dlg = new SaveFileDialog();
                    dlg.Filter = "dct | *.dct";
                    if (dlg.ShowDialog() == true)
                    {
                        using (var stream = File.Open(dlg.FileName, FileMode.Create))
                        {
                            SerializeResult(stream);
                        }
                    }
                }, () => { return DictationViewModel != null; });
            }
        }

        /// <summary>
        /// Save compared result to html file
        /// </summary>
        public ICommand SaveToHtmlCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    SaveFileDialog dlg = new SaveFileDialog();
                    dlg.Filter = "HTML | *.html";
                    if (dlg.ShowDialog() == true)
                    {
                        File.WriteAllText(dlg.FileName, DictationViewModel.SaveToHtml(Path.GetFileNameWithoutExtension(dlg.FileName)));
                    }
                }, () => { return DictationViewModel != null && DictationViewModel.ComparedText != null; });
            }
        }

        public ICommand CloseCommand
        {
            get { return new RelayCommand(Close, () => { return DictationViewModel != null; }); }
        }

        public ICommand MinimiceCommand
        {
            get { return new RelayCommand(Minimice); }
        }

        public ICommand MaximiceCommand
        {
            get { return new RelayCommand(Maximice); }
        }

        public ICommand ExitCommand
        {
            get { return new RelayCommand(Exit); }
        }

        #endregion

        #region Methods

        private void SerializeResult(FileStream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, MediaPlayerViewModel.MediaPath);
            formatter.Serialize(stream, DictationViewModel.GetSaveResult());
        }

        private void DeserializeResult(FileStream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            string mediaPath = formatter.Deserialize(stream) as string;
            var result = formatter.Deserialize(stream) as SaveResult;

            loadDct = true;
            MediaPlayerViewModel.LoadMedia(mediaPath);
            DictationViewModel = new DictationViewModel();
            DictationViewModel.SetResult(result);
        }

        private void HandleMediaLoaded(bool success)
        {
            if (loadDct)
            {
                loadDct = false;
                return;
            }

            if (!success)
                return;

            if (DictationViewModel != null)
            {
                MessageBoxResult result = MessageBox.Show(
                    Application.Current.MainWindow,
                    "Click Yes to star a new dictation. Click No to just load media.",
                    "Are you sure to start a new dictation?",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question);

                if (result == MessageBoxResult.Yes)
                {
                    CheckSave();
                }
                else if (result == MessageBoxResult.No)
                {
                    return;
                }
            }
            DictationViewModel = new DictationViewModel();
        }

        private MessageBoxResult CheckSave()
        {
            if (DictationViewModel != null && !DictationViewModel.Saved)
            {
                MessageBoxResult save = MessageBox.Show(
                    Application.Current.MainWindow,
                    "Do you want to save changes you made?",
                    "DictationCool",
                    MessageBoxButton.YesNoCancel,
                    MessageBoxImage.Question);

                if (save == MessageBoxResult.Yes)
                {
                    SaveFileCommand.Execute(null);
                }

                return save;
            }
            return MessageBoxResult.No;
        }

        private void Close()
        {
            if (CheckSave() != MessageBoxResult.Cancel)
            {
                DictationViewModel = null;
                MediaPlayerViewModel.StopCommand.Execute(null);
            }
        }

        private void Minimice()
        {
            if (Application.Current.MainWindow.WindowState == WindowState.Minimized)
            {
                Application.Current.MainWindow.Opacity = 1;
                Application.Current.MainWindow.WindowState = WindowState.Normal;
            }
            else
            {
                Application.Current.MainWindow.WindowState = WindowState.Minimized;
            }
        }

        private void Maximice()
        {
            if (Application.Current.MainWindow.WindowState == WindowState.Maximized)
            {
                Application.Current.MainWindow.Opacity = 1;
                Application.Current.MainWindow.WindowState = WindowState.Normal;
            }
            else
            {
                Application.Current.MainWindow.WindowState = WindowState.Maximized;
            }
        }

        private void Exit()
        {
            if (CheckSave() != MessageBoxResult.Cancel)
            {
                Application.Current.Shutdown();
            }
        }

        #endregion

        private bool loadDct;
        private DictationViewModel dictationViewModel;
    }
}